﻿# -*- coding: utf-8 -*-


import wx
import wx.richtext
import Queue
from wx._core import GridBagSizer
import serial
from serial.tools.list_ports import comports
import kd_protocol
import kd_serial
import threading

class MainFrame(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title, size=(1000, 600))
        
        self.RxProtocol = []
        
        self.listPort = list()
        self.PortOpen = False;

        self.RxQ = Queue.Queue();
        self.TxQ = Queue.Queue();

        self.ThreadReceiver = threading.Thread(target=self.ThreadReceive)
        self.ThreadReceiver.setDaemon(True)
        self.ThreadReceiver.start()        
        
        # Serial Port Scan       
        for port, desc, hwid in sorted(comports()):
            self.listPort.append(port)

        #print listPort

        self.InitUI()
        self.Center()
        self.Show()
        
    def InitUI(self):
        
        panel = wx.Panel(self)
        gBagSizer = wx.GridBagSizer(5, 5)
        
        self.statusbar = self.CreateStatusBar()
        self.statusbar.SetStatusText('Disconnect')
        
        # Row 1
        self.xTextPrint = wx.ListCtrl(panel, style=wx.LC_REPORT |wx.SUNKEN_BORDER)
        self.xTextPrint.InsertColumn(1,"Device", width = 50)
        self.xTextPrint.InsertColumn(2,"SubID", width = 50)
        self.xTextPrint.InsertColumn(3,"Cmd", width = 50)
        self.xTextPrint.InsertColumn(4,"Tx (Dev Dong Hoo)", width = 120)
        self.xTextPrint.InsertColumn(5,"Rx (Dev Dong Hoo)", width = 80)
        self.xTextPrint.InsertColumn(6,"Data", width = 150)
        self.xTextPrint.InsertColumn(7,"Protocol", width = 250)
                
        
        self.cPort = wx.ComboBox(panel)
       
        for item in self.listPort:
            self.cPort.Append(item, item.upper())
        
        bRescan = wx.Button(panel, label="Rescan")
        bRescan.Bind(wx.EVT_BUTTON, self.onButtonResecan)
        
        gBagSizer.Add(self.xTextPrint, pos=(0, 0), span=(10, 5), flag= wx.EXPAND, border=5)
        gBagSizer.Add(self.cPort, pos=(0, 5), flag= wx.TOP | wx.LEFT , border=5)
        gBagSizer.Add(bRescan, pos=(0, 6), flag= wx.TOP | wx.LEFT, border=5)
        
        # Row 2
        self.bConnect = wx.Button(panel, label="Connect")
        self.bConnect.Bind(wx.EVT_BUTTON, self.onButtonConnect)
        self.bDisconnect = wx.Button(panel, label="Disconnect")
        self.bDisconnect.Bind(wx.EVT_BUTTON, self.onButtonDisconnect)
                
        gBagSizer.Add(self.bConnect, pos=(1, 5), flag= wx.TOP | wx.LEFT, border=5)
        gBagSizer.Add(self.bDisconnect, pos=(1, 6), flag= wx.TOP | wx.LEFT, border=5)
        
        # ROW 3
        sLine = wx.StaticLine(panel)
        gBagSizer.Add(sLine, pos=(2, 5), span=(1, 2), flag = wx.EXPAND | wx.BOTTOM, border=5)        

        # Row 4
        lPcDevice = wx.StaticText(panel, label="PC Device ID")
        cPcDevice = wx.ComboBox(panel)
        gBagSizer.Add(lPcDevice, pos=(3, 5), flag= wx.LEFT, border=5)
        gBagSizer.Add(cPcDevice, pos=(3, 6), flag= wx.LEFT, border=5)

        # Row 5
        lPcDong = wx.StaticText(panel, label="PC Dong ID")
        xPcdong = wx.TextCtrl(panel)
        
        gBagSizer.Add(lPcDong, pos=(4, 5), flag= wx.LEFT, border=5)
        gBagSizer.Add(xPcdong, pos=(4, 6), flag= wx.LEFT, border=5)

        # Row 6
        lPcHoo = wx.StaticText(panel, label="PC Hoo ID")
        xPcHoo = wx.TextCtrl(panel)
        
        gBagSizer.Add(lPcHoo, pos=(5, 5), flag= wx.LEFT, border=5)
        gBagSizer.Add(xPcHoo, pos=(5, 6), flag= wx.LEFT, border=5)
        
        # ROW 7
        sLine = wx.StaticLine(panel)
        gBagSizer.Add(sLine, pos=(6, 5), span=(1, 2), flag = wx.EXPAND | wx.BOTTOM, border=5)        
        
        # Row 8
        lTarDevice = wx.StaticText(panel, label="Target Device ID")
        cTarDevice = wx.ComboBox(panel)
        
        gBagSizer.Add(lTarDevice, pos=(7, 5), flag= wx.LEFT, border=5)
        gBagSizer.Add(cTarDevice, pos=(7, 6), flag= wx.LEFT, border=5)

        # Row 9
        lTarDong = wx.StaticText(panel, label="Target Dong ID")
        xTardong = wx.TextCtrl(panel)
        
        gBagSizer.Add(lTarDong, pos=(8, 5), flag= wx.LEFT, border=5)
        gBagSizer.Add(xTardong, pos=(8, 6), flag= wx.LEFT, border=5)

        # Row 10
        lTarHoo = wx.StaticText(panel, label="Target Hoo ID")
        xTarHoo = wx.TextCtrl(panel)
        
        gBagSizer.Add(lTarHoo, pos=(9, 5), flag= wx.LEFT, border=5)
        gBagSizer.Add(xTarHoo, pos=(9, 6), flag= wx.LEFT, border=5)        
        
        #
        
        self.bDisconnect.Disable()
        
        gBagSizer.AddGrowableCol(2)
        panel.SetSizerAndFit(gBagSizer)
    
    def TextListInLine(self, tList):
        
        pos = self.xTextPrint.Append(tList[1]) #device
        self.xTextPrint.SetStringItem(pos, 1, tList[2])
        self.xTextPrint.SetStringItem(pos, 2, tList[3])
        self.xTextPrint.SetStringItem(pos, 3, tList[5] + tList[7] + tList[7] + tList[9] + tList[10])
        self.xTextPrint.SetStringItem(pos, 4, tList[6] + tList[11] + tList[12] + tList[13] + tList[14])
        
        tString1 = ''.join(tList[15:-2])
        tString2 = ''.join(tList[:])
                
        self.xTextPrint.SetStringItem(pos, 5, tString1)
        self.xTextPrint.SetStringItem(pos, 6, tString2)

    def ThreadReceive(self):
        
        PrtCnt = 0;
        prtLength = 0
        
        try:       
            while True:
                if not self.RxQ.empty():
                    data = self.RxQ.get(1).encode("hex").upper()
                    PrtCnt += 1
                    if data =='F7':
                        PrtCnt = 1
                        prtLength = 5
                        self.RxProtocol = []
                        self.RxProtocol.append(data + ' ')
                    elif PrtCnt == 5 and PrtCnt <= (prtLength):
                        prtLength = int(data,16)
                        self.RxProtocol.append(data + ' ')
                    elif PrtCnt < ( prtLength + 7):
                        self.RxProtocol.append(data + ' ')
                    else:
                        if PrtCnt > 5:                            
                            self.RxProtocol.append(data + ' ')
                            self.TextListInLine(self.RxProtocol)
                            
                        PrtCnt = 0
                        prtLength = 0
        except:
            print 'Thread Receive'
            raise
        
    def onButtonResecan(self, event):
        self.listPort = []
        # Serial Port Scan       
        for port, desc, hwid in sorted(comports()):
            self.listPort.append(port)
        
    def onButtonConnect(self, event):
        self.PortOpen = True;
        portdata = self.cPort.GetValue()
        self.kdSerial = kd_serial.Miniterm(portdata ,9600, self.RxQ, self.TxQ )
        self.kdSerial.start()
        self.bConnect.Disable()
        self.bDisconnect.Enable()
        self.statusbar.SetStatusText('Connect ' + portdata + ' ' + '9600' )
        
    def onButtonDisconnect(self, event):
        self.PortOpen = False;
        self.bConnect.Enable()
        self.bDisconnect.Disable()
        self.statusbar.SetStatusText('Disconnect')
        self.kdSerial.stop()
        self.kdSerial.join()

app = wx.App(False)
frame = MainFrame(None, -1, 'Calculator')
app.MainLoop()
